var util = require('util');
var fs = require('fs');
require('buffer');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var debug = false;

/**
 * This module fucking logs things. It's 1 AM and I'm on my 7th cup of coffee.
 * Sleep is for bitches.
 * 
 * @author jmanero
 * @class Message
 * 
 * @requires mongoose
 * @requires util
 * @requires fs
 * 
 * @constructor
 * 
 * @TODO Check for a connection. If no connection, try to open a file, dump
 *       logs, and exit with an error.
 * 
 */
var Message = new Schema({
	/**
	 * WTF is this message?
	 * 
	 * @type String
	 * @memberOf message
	 */
	level : {
		type : String,
		enum : [ 'Info', 'Warning', 'Error', 'FUCK' ]
	},
	/**
	 * Error Type. only for errors.
	 * 
	 * @type String
	 * @memberOf message
	 */
	type : {
		type : String,
		'default' : 'None.'
	},
	/**
	 * The message content
	 * 
	 * @type String
	 * @memberOf message
	 */
	message : {
		type : String,
	},
	/**
	 * The stack trace of an error. Only for errors. Duh.
	 * 
	 * @type String
	 * @memberOf message
	 */
	stack : {
		type : String,
		'default' : 'None.'
	},
	/**
	 * Time Stamp
	 * 
	 * @type Date
	 * @memberOf message
	 */
	trampstamp : {
		type : Date,
		'default' : Date.now
	}
});

/**
 * Set log level and debug mode and open log file
 * 
 *  @memnerOf Message
 */
Message.statics.startup = function(level, setDebug) {
	var message = this;
	message.level = level;
	debug = setDebug;

	// Open a log file for database failures
	fs.open('./Logs/message.log', 'a', function(e, fd) {
		message.errorFile = fd;
	});
};

/**
 * Debugging Information
 * 
 * @memberOf Message
 */
Message.statics.info = function(message) {
	if (this.level < 2)
		return;
	
	if (debug)
		util.log('INFO: ' + message);

	var entry = new model.Message();
	entry.level = 'Info';
	entry.message = message;
	entry.save(function(e) {
		model.Message.fuck(e);
	});
};

/**
 * Warning. Log to database
 * 
 * @memberOf Message
 */
Message.statics.warn = function(message) {
	if (this.level < 1)
		return;
	
	if (debug)
		util.log('WARNING: ' + message);

	var entry = new model.Message();
	entry.level = 'Warning';
	entry.message = message;
	entry.save(function(e) {
		model.Message.fuck(e);
	});
};

/**
 * First pass error handler. Logs errors to database
 * 
 * @memberOf Message
 */
Message.statics.error = function(e) {
	if (e) {
		if (debug) {
			util.log("FUCK! There was an error!\n-----------");
			util.puts(e.type);
			util.puts(e.message);
			util.puts(e.stack);
		}

		var entry = new model.Message();
		entry.level = 'Error';
		entry.type = e.type;
		entry.message = e.message;
		entry.stack = e.stack;
		entry.save(function(e) {
			model.Message.fuck(e);
		});
	}
};

/**
 * Last ditch effort to log a failure if the database operation fails
 * 
 * @memberOf Message
 */
Message.statics.fuck = function(e) {
	if (e) {
		var mBuf = new Buffer(
				Date.now()
						+ "------------\n"
						+ e.type
						+ "\n"
						+ e.message
						+ "\n-------------------------------------\n"
						+ e.stack
						+ "--------------------------------------------------------------------------");

		if (debug)
			util.puts(mBuf.toString());
		
		fs.write(this.errorFile, mBuf, 0, mBuf.length);
	}
};

model.Message = connection.model('Message', Message);